package com.ler.fast.factory;

import com.ler.fast.annotation.FooAnnotation;
import java.util.Set;
import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.env.Environment;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.filter.AnnotationTypeFilter;

/**
 * @author lww
 * @date 2020-07-15 18:28
 */
public class FooFactoryBeanRegister implements ImportBeanDefinitionRegistrar {

    private final Environment environment;

    FooFactoryBeanRegister(Environment environment) {
        this.environment = environment;
    }

    @Override
    public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
        //扫描含有自定义注解FooAnnotation的的所有类
        String className = metadata.getClassName();
        String basePackage = className.substring(0, className.lastIndexOf("."));
        ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(false, environment);
        provider.addIncludeFilter(new AnnotationTypeFilter(FooAnnotation.class));
        Set<BeanDefinition> candidateComponents = provider.findCandidateComponents(basePackage);

        for (BeanDefinition beanDefinition : candidateComponents) {
            AnnotationMetadata annotationMetadata = ((AnnotatedBeanDefinition) beanDefinition).getMetadata();
            registerBeanDefinition(registry, annotationMetadata);
        }
    }

    public void registerBeanDefinition(BeanDefinitionRegistry registry, AnnotationMetadata annotationMetadata) {
        String className = annotationMetadata.getClassName();
        //在这里把FooFactoryBean与Bean绑定起来
        BeanDefinitionBuilder definition = BeanDefinitionBuilder.genericBeanDefinition(FooFactoryBean.class);
        AbstractBeanDefinition beanDefinition = definition.getBeanDefinition();
        BeanDefinitionHolder holder = new BeanDefinitionHolder(beanDefinition, className);
        BeanDefinitionReaderUtils.registerBeanDefinition(holder, registry);
    }

}
